/******************************************************************************
 * FileName:    gwin_main_task.c
 * Desc:        main
 *
 *
 * Author:      Lin
 * Notes:
 *
 ******************************************************************************/

/*-------------------------- Includes ---------------------------------------*/
#include "gwin_global_data.h"
#include "gwin_global_config.h"

#include "gwin_main_task.h"
#include "gwin_motor_task.h"
#include "gwin_protocol_task.h"


/*-------------------------- Macro Definitions ------------------------------*/
#define LOCAL_DEBUG_EN                      ( 0 )
#if LOCAL_DEBUG_EN
#define GWIN_DEBUG(...)                     USER_DEBUG(__VA_ARGS__)
#else
#define GWIN_DEBUG(...)
#endif


/*-------------------------- Type Declarations ------------------------------*/

/*-------------------------- Global Variables -------------------------------*/
/**
 * @brief 系统参数
 */
system_param_t system_param = { 0 };


/*-------------------------- Local Variables --------------------------------*/
static void *gwin_main_task_timer_one_second = NULL;


/*-------------------------- Functions Declarations -------------------------*/
static void gwin_main_task(void *arg);
static void gwin_main_one_second_callback(void *arg);

static uint8_t gwin_main_get_system_upload_is_no_limit(uint8_t system_upload_index);
static void gwin_main_motor_start(uint8_t target_position);

static void gwin_main_power_on(void);
static void gwin_main_factory_reset(void);

static void gwin_main_task_cfg_msg_handle(gwin_main_task_msg_t *msg);
static void gwin_main_task_timer_msg_handle(gwin_main_task_msg_t *msg);
static void gwin_main_task_btn_msg_handle(gwin_main_task_msg_t *msg);
static void gwin_main_task_motor_msg_handle(gwin_main_task_msg_t *msg);
static void gwin_main_task_extern_action_msg_handle(gwin_main_task_msg_t *msg);


/*-------------------------- Functions Definitions --------------------------*/

/**
 * @brief 按键
 */
void gwin_main_btn_event(uint8_t switch_index, uint8_t btn_event)
{
    gwin_main_task_msg_t msg = { 0 };
    msg.type = MAIN_TASK_MSG_TYPE_BTN;
    msg.subtype = btn_event;
    msg.switch_index = switch_index;
    gwin_send_msg_to_main_task(&msg);
}

/**
 * @brief 电机更新
 */
void gwin_main_motor_update(uint8_t current_position)
{
    gwin_main_task_msg_t msg = { 0 };
    msg.type = MAIN_TASK_MSG_TYPE_MOTOR;
    msg.subtype = MAIN_TASK_MSG_MOTOR_SUBTYPE_UPDATE;
    msg.current_position = current_position;
    gwin_send_msg_to_main_task(&msg);
}

/**
 * @brief 电机空闲
 */
void gwin_main_motor_idle(uint8_t current_position)
{
    gwin_main_task_msg_t msg = { 0 };
    msg.type = MAIN_TASK_MSG_TYPE_MOTOR;
    msg.subtype = MAIN_TASK_MSG_MOTOR_SUBTYPE_IDLE;
    msg.current_position = current_position;
    gwin_send_msg_to_main_task(&msg);
}

/**
 * @brief 外部动作
 */
void gwin_main_extern_action(uint8_t action)
{
    gwin_main_task_msg_t msg = { 0 };
    msg.type = MAIN_TASK_MSG_TYPE_EX_ACT;
    msg.subtype = action;
    gwin_send_msg_to_main_task(&msg);
}

/**
 * @brief 外部动作
 */
void gwin_main_extern_action_with_param(uint8_t action, uint32_t param)
{
    gwin_main_task_msg_t msg = { 0 };
    msg.type = MAIN_TASK_MSG_TYPE_EX_ACT;
    msg.subtype = action;
    msg.ext_param = param;
    gwin_send_msg_to_main_task(&msg);
}

/**
 * @brief 设置参数 修改
 */
void gwin_main_cfg_set(uint32_t cfg_index, uint32_t value)
{
    gwin_main_task_msg_t msg = { 0 };
    msg.type = MAIN_TASK_MSG_TYPE_CFG;
    msg.subtype = cfg_index;
    msg.action_type = MAIN_TASK_MSG_CFG_ACT_TYPE_SET;
    msg.cfg_value = value;
    gwin_send_msg_to_main_task(&msg);
}
/**
 * @brief 设置参数 读取
 *          保证主任务优先级最高！！！保证低优先级任务调用！！！否则 gwin_main_cfg_get 会有问题！！！
 */
void gwin_main_cfg_get(uint32_t cfg_index, uint32_t value_addr)
{
    gwin_main_task_msg_t msg = { 0 };
    msg.type = MAIN_TASK_MSG_TYPE_CFG;
    msg.subtype = cfg_index;
    msg.action_type = MAIN_TASK_MSG_CFG_ACT_TYPE_GET;
    msg.cfg_value = value_addr;
    gwin_send_msg_to_main_task(&msg);
}
/**
 * @brief 设置参数 复位
 */
void gwin_main_cfg_reset(uint32_t cfg_index, uint32_t value)
{
    gwin_main_task_msg_t msg = { 0 };
    msg.type = MAIN_TASK_MSG_TYPE_CFG;
    msg.subtype = cfg_index;
    msg.action_type = MAIN_TASK_MSG_CFG_ACT_TYPE_RESET;
    msg.cfg_value = value;
    gwin_send_msg_to_main_task(&msg);
}
/**
 * @brief 设置参数 复位
 */
void gwin_main_cfg_reset2(uint32_t cfg_index, uint32_t value)
{
    gwin_main_task_msg_t msg = { 0 };
    msg.type = MAIN_TASK_MSG_TYPE_CFG;
    msg.subtype = cfg_index;
    msg.action_type = MAIN_TASK_MSG_CFG_ACT_TYPE_RESET2;
    msg.cfg_value = value;
    gwin_send_msg_to_main_task(&msg);
}
/**
 * @brief 设置参数 删除
 */
void gwin_main_cfg_delete(uint32_t cfg_index, uint32_t value)
{
    gwin_main_task_msg_t msg = { 0 };
    msg.type = MAIN_TASK_MSG_TYPE_CFG;
    msg.subtype = cfg_index;
    msg.action_type = MAIN_TASK_MSG_CFG_ACT_TYPE_DELETE;
    msg.cfg_value = value;
    gwin_send_msg_to_main_task(&msg);
}


/**
 * @brief 判断一个属性是否不受限制
 */
static uint8_t gwin_main_get_system_upload_is_no_limit(uint8_t system_upload_index)
{
    uint8_t ret = 0;

//    if (system_upload_index == SYS_UPLOAD_INDEX_CURTAIN_STATE)
//    {
//        ret = 1;
//    }

    return ret;
}

/**
 * @brief 电机开始
 */
static void gwin_main_motor_start(uint8_t target_position)
{

}



/**
 * @brief 上电初始化
 */
static void gwin_main_power_on(void)
{
    SYSTEM_DEBUG("");
    SYSTEM_DEBUG("--- SYSTEM POWER ON ---");
    SYSTEM_DEBUG("--- build time : \t%s %s", __DATE__, __TIME__);
    SYSTEM_DEBUG("--- firmware : \t%s", GWIN_FW_NAME_TOTAL);
    SYSTEM_DEBUG("--- model : \t%s", GWIN_PRODUCT_MODEL);
    SYSTEM_DEBUG("--- pid : \t\t%d", GWIN_PRODUCT_PID);
    SYSTEM_DEBUG("");

    // 上电开始计秒
    system_param.second = 0;
    os_timer_start(gwin_main_task_timer_one_second, 0);

    gwin_main_motor_start(0);
}

/**
 * @brief 重新配网
 */
void gwin_main_network_reset(uint8_t network_restore_manual)
{
    // 重置网络要重置所有参数
    gwin_custom_record_reset_all();

    system_param.network.provisioned = 0;
    gwin_custom_record_save(RECORD_ID_NETWORK);

    if (network_restore_manual)
    {
        network_restore();
    }
}

/**
 * @brief 重置
 */
static void gwin_main_factory_reset(void)
{
    GWIN_DEBUG("");

    gwin_custom_record_reset_all();
    system_reboot();
}


/**
 * @brief 设置消息处理
 */
static void gwin_main_task_cfg_msg_handle(gwin_main_task_msg_t *msg)
{
    uint16_t subtype = msg->subtype;
    uint8_t action_type = msg->action_type;

    // 某些条件不响应外部指令
    if (system_param.factory_test)
    {
        GWIN_DEBUG("factory test!!!");
        return;
    }
    if (system_param.factory_reset)
    {
        GWIN_DEBUG("factory reset!!!");
        return;
    }
    if (system_param.network_reset && action_type != MAIN_TASK_MSG_CFG_ACT_TYPE_GET)
    {
        GWIN_DEBUG("network reset!!!");
        return;
    }
    if (system_param.ota_state && subtype > MAIN_TASK_MSG_CFG_SUBTYPE_OTA_STATE)
    {
        GWIN_DEBUG("ota is running!!!");
        return;
    }

    if (action_type != MAIN_TASK_MSG_CFG_ACT_TYPE_SET
            && action_type != MAIN_TASK_MSG_CFG_ACT_TYPE_GET
            && action_type != MAIN_TASK_MSG_CFG_ACT_TYPE_RESET
            && action_type != MAIN_TASK_MSG_CFG_ACT_TYPE_RESET2
            && action_type != MAIN_TASK_MSG_CFG_ACT_TYPE_DELETE)
    {
        GWIN_DEBUG("Error : cfg action type none!!!");
        return;
    }
    if (action_type == MAIN_TASK_MSG_CFG_ACT_TYPE_GET && msg->cfg_value == 0)           // 获取的时候，传了空指针，会死机
    {
        GWIN_DEBUG("Error : cfg action get %d pointer is null!!!", subtype);
        return;
    }

    GWIN_DEBUG("subtype = %d, action_type = %d, cfg_value = %u", subtype, action_type, msg->cfg_value);

    switch(subtype)
    {
        case MAIN_TASK_MSG_CFG_SUBTYPE_NETWORK:
            if (action_type == MAIN_TASK_MSG_CFG_ACT_TYPE_GET)
            {

            }
            else
            {
                // 这里不代表已经连上网关！！！！！
                uint8_t cfg_value = msg->cfg_value;
                uint8_t network_provisioned = cfg_value ? 1 : 0;
                system_param.network_state = network_provisioned;
                if (system_param.network_state && !system_param.setting.upload_total)  // 没有上报过，系统参数强制全部上报一次
                {
                    system_param.system_upload_force_wait = FORCE_UPLOAD_TIME_NETWORK;      // 配网成功后，延时参数全量上报，防止在选择界面，上报影响SDK原有的逻辑
                }
                if (system_param.network.provisioned != network_provisioned)                // 上电就会发出配网状态，做个锁，防止频繁修改flash
                {
                    system_param.network.provisioned = network_provisioned;
                    gwin_custom_record_save(RECORD_ID_NETWORK);
                }
            }
            break;

        case MAIN_TASK_MSG_CFG_SUBTYPE_GATT:
            if (action_type == MAIN_TASK_MSG_CFG_ACT_TYPE_GET)
            {

            }
            else
            {
                uint8_t cfg_value = msg->cfg_value;
                uint8_t gatt_state = cfg_value ? 1 : 0;
                if (system_param.gatt_state != gatt_state)                                  // 没有蓝牙直连到有蓝牙直连，系统参数强制全部上报一次
                {
                    system_param.gatt_state = gatt_state;
                    if (system_param.gatt_state && !system_param.setting.upload_total)
                    {
                        // LIN MARK 230424 ： 蓝牙直连不能做全量上报，因为网关连接，插件会通过蓝牙直连获取版本号信息，做OTA
                        // 没有上报过，系统参数强制全部上报一次
                        system_param.system_upload_force_wait = FORCE_UPLOAD_TIME_GATT; // 连接成功后，延时参数全量上报，防止在选择界面，上报影响SDK原有的逻辑
                    }
                }
            }
            break;

        case MAIN_TASK_MSG_CFG_SUBTYPE_OTA_STATE:
            if (action_type == MAIN_TASK_MSG_CFG_ACT_TYPE_GET)
            {

            }
            else
            {
                uint8_t cfg_value = msg->cfg_value;
                system_param.ota_state = cfg_value ? 1 : 0;
            }
            break;

        case MAIN_TASK_MSG_CFG_SUBTYPE_CURTAIN_STATE:
            if (action_type == MAIN_TASK_MSG_CFG_ACT_TYPE_GET)
            {
                uint32_t *value_addr = (uint32_t *)msg->cfg_value;
                *value_addr = system_param.curtain.curtain_state;
            }
            else
            {
                uint8_t curtain_state = msg->cfg_value;
                curtain_state = MIN(curtain_state, CURTAIN_STATE_MAX - 1);
                if (curtain_state != system_param.curtain.curtain_state)
                {
                    // TODO
                }
            }
            break;

        case MAIN_TASK_MSG_CFG_SUBTYPE_CURRENT_POSITION:
            if (action_type == MAIN_TASK_MSG_CFG_ACT_TYPE_GET)
            {
                uint32_t *value_addr = (uint32_t *)msg->cfg_value;
                *value_addr = system_param.curtain.current_position;
            }
            else
            {
                uint8_t position = msg->cfg_value;
                position = MIN(position, CURTAIN_POSITION_MAX);
                if (position != system_param.curtain.current_position)
                {
                    // TODO
                }
            }
            // 协议栈定期取值上报给后台，或者下发，保存这次上报值
            if (system_param.system_upload.last.current_position != system_param.curtain.current_position)
            {
                system_param.system_upload.last.current_position = system_param.curtain.current_position;
                gwin_custom_record_save(RECORD_ID_SYSTEM_UPLOAD);
            }
            break;

        case MAIN_TASK_MSG_CFG_SUBTYPE_TARGET_POSITION:
            if (action_type == MAIN_TASK_MSG_CFG_ACT_TYPE_GET)
            {
                uint32_t *value_addr = (uint32_t *)msg->cfg_value;
                *value_addr = system_param.curtain.target_position;
            }
            else
            {
                uint8_t position = msg->cfg_value;
                position = MIN(position, CURTAIN_POSITION_MAX);
                if (position != system_param.curtain.target_position)
                {
                    // TODO
                }
            }
            // 协议栈定期取值上报给后台，或者下发，保存这次上报值
            if (system_param.system_upload.last.target_position != system_param.curtain.target_position)
            {
                system_param.system_upload.last.target_position = system_param.curtain.target_position;
                gwin_custom_record_save(RECORD_ID_SYSTEM_UPLOAD);
            }
            break;

        case MAIN_TASK_MSG_CFG_SUBTYPE_DIRECTION:
            if (action_type == MAIN_TASK_MSG_CFG_ACT_TYPE_GET)
            {
                uint32_t *value_addr = (uint32_t *)msg->cfg_value;
                *value_addr = system_param.curtain.direction;
            }
            else
            {
                uint8_t direction = (msg->cfg_value > 0);
                if (direction != system_param.curtain.direction)
                {
                    // TODO
                }
            }
            // 协议栈定期取值上报给后台，或者下发，保存这次上报值
            if (system_param.system_upload.last.direction != system_param.curtain.direction)
            {
                system_param.system_upload.last.direction = system_param.curtain.direction;
                gwin_custom_record_save(RECORD_ID_SYSTEM_UPLOAD);
            }
            break;

        case MAIN_TASK_MSG_CFG_SUBTYPE_SPEED_LEVEL:
            if (action_type == MAIN_TASK_MSG_CFG_ACT_TYPE_GET)
            {
                uint32_t *value_addr = (uint32_t *)msg->cfg_value;
                *value_addr = system_param.curtain.speed_level;
            }
            else
            {
                uint8_t speed_level = msg->cfg_value;
                speed_level = MIN(speed_level, SPEED_LEVEL_MAX - 1);
                if (speed_level != system_param.curtain.speed_level)
                {
                    // TODO
                }
            }
            // 协议栈定期取值上报给后台，或者下发，保存这次上报值
            if (system_param.system_upload.last.speed_level != system_param.curtain.speed_level)
            {
                system_param.system_upload.last.speed_level = system_param.curtain.speed_level;
                gwin_custom_record_save(RECORD_ID_SYSTEM_UPLOAD);
            }
            break;

        case MAIN_TASK_MSG_CFG_SUBTYPE_STROKE_MIN:
            if (action_type == MAIN_TASK_MSG_CFG_ACT_TYPE_GET)
            {
                uint32_t *value_addr = (uint32_t *)msg->cfg_value;
                *value_addr = system_param.setting.stroke_min;
            }
            else
            {
                uint8_t stroke_min = msg->cfg_value;
                stroke_min = MAX(stroke_min, STROKE_MIN_MIN);
                stroke_min = MIN(stroke_min, STROKE_MIN_MAX);
                if (stroke_min != system_param.setting.stroke_min)
                {
                    // TODO
                }
            }
            break;

        case MAIN_TASK_MSG_CFG_SUBTYPE_STROKE_MAX:
            if (action_type == MAIN_TASK_MSG_CFG_ACT_TYPE_GET)
            {
                uint32_t *value_addr = (uint32_t *)msg->cfg_value;
                *value_addr = system_param.setting.stroke_max;
            }
            else
            {
                uint8_t stroke_max = msg->cfg_value;
                stroke_max = MAX(stroke_max, STROKE_MAX_MIN);
                stroke_max = MIN(stroke_max, STROKE_MAX_MAX);
                if (stroke_max != system_param.setting.stroke_max)
                {
                    // TODO
                }
            }
            break;

        case MAIN_TASK_MSG_CFG_SUBTYPE_NODE_MODE:
            if (action_type == MAIN_TASK_MSG_CFG_ACT_TYPE_GET)
            {
                uint32_t *value_addr = (uint32_t *)msg->cfg_value;
                *value_addr = system_param.setting.node_mode;
            }
            else
            {
                uint8_t node_mode = msg->cfg_value;
                node_mode = MIN(node_mode, NODE_MODE_MAX - 1);
                if (node_mode != system_param.setting.node_mode)
                {
                    // TODO
                }
            }
            break;

        case MAIN_TASK_MSG_CFG_SUBTYPE_PRODUCT_CFG:
            if (action_type == MAIN_TASK_MSG_CFG_ACT_TYPE_GET)
            {
                uint32_t *value_addr = (uint32_t *)msg->cfg_value;
                memcpy(value_addr, &system_param.product_cfg, sizeof(uint32_t));
            }
            else
            {

            }
            break;

        default:
            GWIN_DEBUG("Error : subtype of cfg msg is unknown %d !!!", subtype);
            break;
    }

    if (action_type == MAIN_TASK_MSG_CFG_ACT_TYPE_GET)
    {
        GWIN_DEBUG("cfg get value = %u", *(uint32_t *)msg->cfg_value);
    }
}

/**
 * @brief 定时器消息处理
 */
static void gwin_main_task_timer_msg_handle(gwin_main_task_msg_t *msg)
{
    uint16_t subtype = msg->subtype;

    switch(subtype)
    {
        case MAIN_TASK_MSG_TIMER_SUBTYPE_ONE_SECOND:
            {
                system_param.second++;

                // 测试代码
                USER_DEBUG("second = %d", system_param.second);
                gwin_motor_set_pwm(0, system_param.second % 11 * 10 * PWM_CNT_MAX / 100);
                gwin_motor_set_pwm(1, (10 - system_param.second % 11) * 10 * PWM_CNT_MAX / 100);

                // 配网、蓝牙直连初期，系统参数强制延时，马上上报可能死机
                if (system_param.system_upload_force_wait > 0)
                {
                    system_param.system_upload_force_wait--;
                    if (system_param.system_upload_force_wait == 0)
                    {
                        for (uint8_t i = 0; i < SYS_UPLOAD_INDEX_MAX; i++)
                        {
                            gwin_save_general_clock(&system_param.system_upload_clock[i]);
                        }
                    }
                }
                // 补发机制
                if (system_param.system_upload.wait > 0 && system_param.second == WAIT_UPLOAD_MIOT_RESEND_TIME)
                {
                    for (uint8_t i = 0; i < SYS_UPLOAD_INDEX_MAX; i++)
                    {
                        if (BIT_CHK_1(system_param.system_upload.wait, i))
                        {
                            gwin_save_general_clock(&system_param.system_upload_clock[i]);
                        }
                    }
                }

                // 查看系统上报参数，上报
                if (system_param.network_state && system_param.network.provisioned)
                {
                    uint32_t upload_value = 0;
                    uint8_t upload_success = 1;
                    uint8_t upload_cnt = 0;
                    uint8_t need_upload = 0;
                    uint8_t need_save_system_upload_last = 0;
                    uint32_t wait_upload_miot = system_param.system_upload.wait;

                    for (uint8_t i = 0; i < SYS_UPLOAD_INDEX_MAX; i++)
                    {
                        if ((gwin_get_general_clock_is_start(&system_param.system_upload_clock[i])
                                        && (system_param.gatt_state                                                         // 蓝牙直连，直接发
                                                || gwin_main_get_system_upload_is_no_limit(i)))                             // mesh连接，某些属性不受限制，直接发
                                || gwin_pass_general_clock(system_param.system_upload_clock[i], SYS_UPLOAD_TIME * 1000))    // mesh连接，普通属性延时发
                        {
                            if (system_upload_map[i].upload_action != NULL)
                            {
                                upload_value = 0;
                                memcpy(&upload_value, system_upload_map[i].memory_addr, system_upload_map[i].size);
                                need_upload = 0;
                                if (system_upload_map[i].last_value != NULL)
                                {
                                    uint32_t last_value = 0;
                                    memcpy(&last_value, system_upload_map[i].last_value, system_upload_map[i].size);
                                    if (upload_value != last_value)
                                    {
                                        need_upload = 1;
                                    }
                                    GWIN_DEBUG("check upload [%d]:value = %d %d, need_upload = %d", i, upload_value, last_value, need_upload);
                                }
                                else
                                {
                                    need_upload = 1;
                                }
                                if (need_upload)
                                {
                                    if (upload_success)                         // 只要有一个失败，接下来所有参数，本次都不再尝试发送（重点参数请往前移动）
                                    {
                                        ++upload_cnt;
                                        upload_success = system_upload_map[i].upload_action(upload_value);
                                        GWIN_DEBUG("upload action [%d]:value = %u, success = %d", i, upload_value, upload_success);

                                        // 上报成功后才能修改上次上报的值并且保存
                                        if (upload_success && system_upload_map[i].last_value != NULL)
                                        {
                                            need_save_system_upload_last = 1;
                                            memcpy(system_upload_map[i].last_value, &upload_value, system_upload_map[i].size);
                                        }
                                    }
                                }
                            }

                            if (!upload_success)
                            {
                                gwin_save_general_clock(&system_param.system_upload_clock[i]);
                            }
                            else
                            {
                                gwin_clear_general_clock(&system_param.system_upload_clock[i]);
                                BIT_CLR(wait_upload_miot, i);

                                if (i == (SYS_UPLOAD_INDEX_MAX - 1))    // 全部发送完
                                {
                                    if (!system_param.setting.upload_total)
                                    {
                                        system_param.setting.upload_total = 1;
                                        gwin_custom_record_save(RECORD_ID_SETTING);
                                    }
                                }
                            }

                            // 限制最多一次性上报，因为：一次性上报很多条都是底层接口malloc压栈，占用内存
                            if (upload_cnt >= SYS_UPLOAD_PER_SECOND_CNT_MAX)
                            {
                                break;
                            }
                        }
                    }

                    // 清除
                    if (system_param.system_upload.wait != wait_upload_miot)
                    {
                        GWIN_DEBUG("wait_upload_miot = %x %x", system_param.system_upload.wait, wait_upload_miot);
                        system_param.system_upload.wait = wait_upload_miot;
                        gwin_custom_record_save(RECORD_ID_SYSTEM_UPLOAD);
                    }

                    // 保存这次上报值
                    if (need_save_system_upload_last)
                    {
                        gwin_custom_record_save(RECORD_ID_SYSTEM_UPLOAD);
                    }
                }
            }
            break;

        default:
            GWIN_DEBUG("Error : subtype of timer msg is unknown %d !!!", subtype);
            break;
    }
}


/**
 * @brief 按键消息处理
 */
static void gwin_main_task_btn_msg_handle(gwin_main_task_msg_t *msg)
{
    // 某些条件不响应按键消息
    if (system_param.ota_state)
    {
        GWIN_DEBUG("ota is running!!!");
        return;
    }

    uint16_t subtype = msg->subtype;
    uint8_t switch_index = msg->switch_index;

    USER_DEBUG("subtype = %d, switch_index = %d", subtype, switch_index);

    switch(subtype)
    {
        case MAIN_TASK_MSG_BTN_SUBTYPE_SINGLE_CLICK:
            {

            }
            break;

        default:
            GWIN_DEBUG("Error : subtype of btn msg is unknown %d !!!", subtype);
            break;
    }
}

/**
 * @brief 电机消息处理
 */
static void gwin_main_task_motor_msg_handle(gwin_main_task_msg_t *msg)
{
    uint16_t subtype = msg->subtype;

    switch(subtype)
    {
        case MAIN_TASK_MSG_MOTOR_SUBTYPE_UPDATE:
            {

            }
            break;

        case MAIN_TASK_MSG_MOTOR_SUBTYPE_IDLE:
            {

            }
            break;

        default:
            GWIN_DEBUG("Error : subtype of motor msg is unknown %d !!!", subtype);
            break;
    }
}

/**
 * @brief 外部动作消息处理
 */
static void gwin_main_task_extern_action_msg_handle(gwin_main_task_msg_t *msg)
{
    // 某些条件不响应外部指令
    if (system_param.factory_test)
    {
        GWIN_DEBUG("factory test!!!");
        return;
    }
    if (system_param.factory_reset)
    {
        GWIN_DEBUG("factory reset!!!");
        return;
    }
    if (system_param.network_reset)
    {
        GWIN_DEBUG("network reset!!!");
        return;
    }
    if (system_param.ota_state)
    {
        GWIN_DEBUG("ota is running!!!");
        return;
    }

    uint16_t subtype = msg->subtype;
    GWIN_DEBUG("subtype = %d", subtype);

    switch(subtype)
    {
        case MAIN_TASK_MSG_EX_ACT_SUBTYPE_CURTAIN_TOGGLE:
            // TODO :
            break;

        case MAIN_TASK_MSG_EX_ACT_SUBTYPE_CALIBRATION:
            // TODO :
            if (system_param.network_state)
            {
                spec_notify_success_do_event(SUCCESS_EVENT_CALIBRATION);
            }
            break;

        case MAIN_TASK_MSG_EX_ACT_SUBTYPE_REMOTE_PAIR_START:
            // TODO :
            if (system_param.network_state)
            {
                spec_notify_success_do_event(SUCCESS_EVENT_REMOTE_PAIR_START);
            }
            break;
        case MAIN_TASK_MSG_EX_ACT_SUBTYPE_REMOTE_PAIR_CLEAR:
            // TODO :
            if (system_param.network_state)
            {
                spec_notify_success_do_event(SUCCESS_EVENT_REMOTE_PAIR_CLEAR);
            }
            break;

        case MAIN_TASK_MSG_EX_ACT_SUBTYPE_NET_RESET:
            gwin_main_network_reset(1);
            break;

        case MAIN_TASK_MSG_EX_ACT_SUBTYPE_FACTORY_TEST:
            break;

        case MAIN_TASK_MSG_EX_ACT_SUBTYPE_FACTORY_RESET:
            gwin_main_factory_reset();
            break;

            // 强制复位所有参数（研发预留接口，防止错误，直接响应）
        case MAIN_TASK_MSG_EX_ACT_SUBTYPE_RESET_ALL_FORCE:
            {
                gwin_custom_record_reset_all_force_force();
                network_restore();
            }
            break;

        default:
            GWIN_DEBUG("Error : subtype of ex act msg is unknown %d !!!", subtype);
            break;
    }
}



/**
 * @brief 任务初始化
 */
void gwin_main_task_init(void)
{
    gwin_main_task_timer_one_second = os_timer_create("gwin_main_one_second", 1000, TRUE, 0, gwin_main_one_second_callback);
    GWIN_OS_TIMER_ASSERT(gwin_main_task_timer_one_second);

    gwin_main_task_msg_t msg = { 0 };
    msg.type = MAIN_TASK_MSG_TYPE_TASK_INIT;
    gwin_send_msg_to_main_task(&msg);
}

/**
 * @brief 定时器 上电计秒
 */
static void gwin_main_one_second_callback(void *arg)
{
    gwin_main_task_msg_t msg = { 0 };
    msg.type = MAIN_TASK_MSG_TYPE_TIMER;
    msg.subtype = MAIN_TASK_MSG_TIMER_SUBTYPE_ONE_SECOND;
    gwin_send_msg_to_main_task(&msg);
}

/**
 * @brief 任务
 */
static void gwin_main_task(void *arg)
{
    gwin_main_task_msg_t *msg = arg;

    switch(msg->type)
    {
        case MAIN_TASK_MSG_TYPE_TASK_INIT:
            gwin_main_power_on();
            break;

        case MAIN_TASK_MSG_TYPE_CFG:
            gwin_main_task_cfg_msg_handle(msg);
            break;

        case MAIN_TASK_MSG_TYPE_TIMER:
            gwin_main_task_timer_msg_handle(msg);
            break;

        case MAIN_TASK_MSG_TYPE_BTN:
            gwin_main_task_btn_msg_handle(msg);
            break;

        case MAIN_TASK_MSG_TYPE_MOTOR:
            gwin_main_task_motor_msg_handle(msg);
            break;

        case MAIN_TASK_MSG_TYPE_EX_ACT:
            gwin_main_task_extern_action_msg_handle(msg);
            break;

        default:
            break;
    }
}


/*-------------------------- END OF FILE ------------------------------------*/

